//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

namespace Microsoft.Research.ProvenanceSubscriberMessageParser
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Research.eResearch.Blackboard.Common;
    using Microsoft.Research.ProvenanceSubscriberCommon.Models;
    using System.Collections.ObjectModel;

    /// <summary>
    /// This class contains the implementation logic of 
    /// the PerformanceDetail parser logic.
    /// </summary>
    class PerformanceDetailParser : AbstractMessageParser
    {
        /// <summary>
        /// Internal class used to store the performance counter map.
        /// </summary>
        internal class PerformanceCounterMap
        {
            public string Concept { get; set; }

            public string Name { get; set; }
        }

        /// <summary>
        /// Colelction of performance Counter maps.
        /// </summary>
        private PerformanceCounterMap[] counterMaps;

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="blackBoardMsgParser">BlackboardMessageParser.</param>
        public PerformanceDetailParser(BlackboardMessageParser blackBoardMsgParser)
            : base(blackBoardMsgParser)
        {
            counterMaps = new PerformanceCounterMap[] 
            { 
                new PerformanceCounterMap { Concept = "trident:CpuResource", Name = "CPU"},
                new PerformanceCounterMap { Concept = "trident:MemoryResource", Name = "Memory"}
            };
        }

        /// <summary>
        /// This function parsers the message for performance details.
        /// </summary>
        /// <param name="message">BlackboardMessage</param>
        public override void Parse(BlackboardMessage message)
        {
            if (IsResourceEvent(message))
            {
                ProvenanceInformationModel provenenceModel = GetProvenanceInfo(message);

                foreach (PerformanceCounterMap counterMap in this.counterMaps)
                {
                    if (message.Keys.Contains(counterMap.Concept))
                    {
                        PerformanceDetailModel perfDetail = GetPerfDetail(message, counterMap);
                        provenenceModel.PerformanceDetail = perfDetail; 
                        //provenenceModel.PerformanceDetailCollection.Add(perfDetail);
                    }
                }

                this.BlackboardMessageParser.RaisePerformanceEvent(provenenceModel);
            }
        }

        /// <summary>
        /// This function is used to get the performance details information from the blackboard msg.
        /// </summary>
        /// <param name="message">BlackboardMessage</param>
        /// <param name="counterMap">PerformanceCounterMap</param>
        /// <returns>PerformanceDetailModel</returns>
        private static PerformanceDetailModel GetPerfDetail(BlackboardMessage message, PerformanceCounterMap counterMap)
        {
            PerformanceDetailModel perfDetail = new PerformanceDetailModel();

            DateTime messageTime;
            if (DateTime.TryParse(message["trident:EventTimestamp"], out messageTime))
            {
                perfDetail.Timestamp = messageTime;
            }

            perfDetail.PerformanceCounterName = counterMap.Name;

            double perfValue;
            if (!double.TryParse(message[counterMap.Concept], out perfValue))
            {
                perfValue = 0;
            }

            perfDetail.Value = perfValue;

            return perfDetail;
        }
    }
}
